package DTI;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

public class Corpus {
	private Vector corpus_files;
	private HashMap corpus_words;
	private int charCount;
	private int fileCount;
	private int wordCount;
	
	private static final float MIN_THRESHOLD = 0.1f;
	private static final float MAX_THRESHOLD = 0.75f;
	
	public Corpus(Options options) throws IOException{
		createCorpus(options);
	}
	
	public void createCorpus(Options options) throws IOException{
		
		corpus_words = new HashMap();
		corpus_files = new Vector();
		
		CorpusFile curr_corpus_file;
		File[] input_files = options.getInputFile();
		InputStream file_input = null;
		char curr_char;
		String curr_word = "";
		boolean isThereStopFile;
		
		//delete
		int curr_line_num = 0;
		boolean newline_check = false;
		boolean newline = true;
		
		//set filecount
		fileCount = input_files.length;
		
		if(options.getWordAnalyzer() == null)
			isThereStopFile = false;
		else
			isThereStopFile = true;
		
		for(int i = 0; i < input_files.length; i++){
			//:)
			if(!input_files[i].exists()){
				throw new FileNotFoundException("Error: file" + input_files[i] + " could not be found. Please check the file name or path and try again.");
			}
			file_input = new FileInputStream(input_files[i]);
			if(file_input == null){
				throw new FileNotFoundException("Error: file" + input_files[i] + " could not be found. Please check the file name or path and try again.");
			}
			
			curr_corpus_file = new CorpusFile(input_files[i].toString(), i);
			corpus_files.add(curr_corpus_file);
				
			while(true){
				try{
					curr_char = (char)file_input.read();
					addChar();
				}
				catch(IOException ioe)
				{
					throw new IOException("unable to read text file");
				}
				
				//if curr_char is EOF or a break character...
				if(curr_char == 65535 || CharacterAnalyzer.isBreakCharacter(curr_char)) {
								
										
					//if curr_word isn't an empty string, meaning we've found a new word...
					if(curr_word.length() != 0){
						//if we need to compare the new word to the stop words...
						if(isThereStopFile && options.getWordAnalyzer().isStopWord(curr_word.toLowerCase())){
							curr_word = "";
						}
						else{
							curr_word = curr_word.toLowerCase();
							int[] counts;
							counts = (int[])corpus_words.get(curr_word);
							if(counts != null){
								counts[i]++;
							//	corpus_words.put(curr_word, counts);
							}
							else{
								counts = new int[fileCount];
								counts[i] = 1;
								corpus_words.put(curr_word, counts);
							}
							curr_word = "";
							addWord();
						}
					}	
					if(curr_char == 65535){
						subtractChar();
						file_input.close();
						break;
					}
				}
				else{
					curr_word = curr_word.concat((new Character(curr_char)).toString());	
				}//end else
			}//end while
		}
		RemoveOutliers();
		
	}
	
	public void RemoveOutliers() {
		Iterator i = corpus_words.keySet().iterator();
		while(i.hasNext()) {
			String s = (String) i.next();
			int [] counts = (int[]) corpus_words.get(s);
			int found = 0;
			for(int loop = 0; loop < counts.length; loop++) {
				if(counts[loop] > 0) {
					found++;
				}
			}
			float weight = (float)found/fileCount;
			if(weight < MIN_THRESHOLD || weight > MAX_THRESHOLD) {
				//corpus_words.remove(s);
				i.remove();
			}
		}
	}
	
	public void addChar(){
		charCount++;
	}
	
	public void subtractChar(){
		charCount--;
	}
	
	public void addWord(){
		wordCount++;
	}
	
	/**
	 * @return Returns the charCount.
	 */
	public int getCharCount() {
		return charCount;
	}
	/**
	 * @return Returns the corpus_files.
	 */
	public Vector getCorpus_files() {
		return corpus_files;
	}
	/**
	 * @return Returns the corpus_words.
	 */
	public HashMap getCorpus_words() {
		return corpus_words;
	}
	/**
	 * @return Returns the fileCount.
	 */
	public int getFileCount() {
		return fileCount;
	}
	/**
	 * @return Returns the wordCount.
	 */
	public int getWordCount() {
		return wordCount;
	}
}
